package com.hatic.contract;

import java.util.Map;

import org.jxstar.control.action.RequestContext;
import org.jxstar.dao.DaoParam;
import org.jxstar.dao.DmDao;
import org.jxstar.service.BusinessObject;
import org.jxstar.util.DateUtil;
import org.jxstar.util.MapUtil;
import org.jxstar.util.StringFormat;
import org.jxstar.util.StringUtil;
import org.jxstar.util.factory.FactoryUtil;

/**
 * 付款计划处理类。
 *
 * @author TonyTan
 * @version 1.0, 2011-11-4
 */
public class PayPlanBO extends BusinessObject {
	private static final long serialVersionUID = 1L;
	
	/**
	 * 支付明细中的公司核准金额为0时，则修改状态为否决，否则修改为申请。
	 * @param payids
	 * @return
	 */
	public String postSaveDet(String[] payids) {
		if (payids == null || payids.length == 0) return _returnSuccess;
		
		for (int i = 0, n = payids.length; i < n; i++) {
			updateSaveDet(payids[i]);
		}
		
		return _returnSuccess;
	}
	
	private boolean updateSaveDet(String payId) {
		String sql = "select check_money, mpay_id from contract_pay where pay_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(payId);
		Map<String,String> mpData = _dao.queryMap(param);
		
		String mpayid = mpData.get("mpay_id");
		double check_money = StringUtil.tonum(mpData.get("check_money"));
		
		//同时修改主表的合计金额
		updateMoney(mpayid);
		
		String plan_status = "1";
		if (check_money == 0) plan_status = "3";
		_log.showDebug("............update pay status:" + plan_status);
		String usql = "update contract_pay set plan_status = ? where pay_id = ?";
		DaoParam uparam = _dao.createParam(usql);
		uparam.addStringValue(plan_status);
		uparam.addStringValue(payId);
		return _dao.update(uparam);
	}
	
	/**
	 * 创建月度付款计划
	 * @param request
	 * @return
	 */
	public String createPlan(RequestContext request ) {
		String deptid = request.getRequestValue("contract_mpay.dept_id");
		String deptname = request.getRequestValue("contract_mpay.dept_name");
		String appdate = request.getRequestValue("contract_mpay.app_date");
		String paymonth = request.getRequestValue("contract_mpay.pay_month");
		String appuser = request.getRequestValue("contract_mpay.app_user");
		String isinfo = request.getRequestValue("contract_mpay.is_info");
		if (deptid.length() == 0 || paymonth.length() == 0) {
			setMessage("没有选择创建单位与统计月份！");
			return _returnFaild;
		}
		//取计划月份值，取当月的第1天
		paymonth = StringFormat.StringToMonth(paymonth);
		
		if (hasMoreMpay(deptid, paymonth,isinfo) > 0) {
			setMessage("同一个单位同一个月不能有两条月度计划！");
			return _returnFaild;
		}
		
		String mpayid = createPlanRecord(deptid, deptname, appdate, paymonth, appuser ,isinfo);
		_log.showDebug("...............创建月度计划ID：" + mpayid);
		
		if (mpayid.length() == 0) {
			setMessage("创建月度付款计划失败！");
			return _returnFaild;
		}
		
		//汇总明细
		statPlan(mpayid);
		
		return _returnSuccess;
	}
	
	//创建月度计划
	private String createPlanRecord(String deptid, String deptname, 
			String appdate, String paymonth, String appuser , String isinfo) {
		Map<String,String> mp = FactoryUtil.newMap();
		mp.put("dept_id", deptid);
		mp.put("dept_name", deptname);
		mp.put("app_date", appdate);
		mp.put("pay_month", paymonth+"-01");
		mp.put("app_user", appuser);
		mp.put("auditing", "0");
		mp.put("is_info", isinfo);
		
		return DmDao.insert("contract_mpay", mp);
	}
	
	/**
	 * 暂时不用。检查付款金额不能超过合同金额
	 * @param mpayIds
	 * @return
	 */
	public String prePlan(String[] mpayIds) {
		if (mpayIds == null || mpayIds.length == 0) {
			setMessage("没有选择合同付款计划！");
			return _returnFaild;
		}
		
		for (int i = 0, n = mpayIds.length; i < n; i++) {
			if (checkMoney(mpayIds[i])) {
				setMessage("累计付款金额大于合同金额，不能提交！");
				return _returnFaild;
			}
		}
		
		return _returnSuccess;
	}
	
	//检查付款金额是否超过合同金额
	private boolean checkMoney(String payId) {
		String sql = "select contract_money, plan_money, pay_money from contract_pay where pay_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(payId);
		
		Map<String,String> mpData = _dao.queryMap(param);
		double pay_money = StringUtil.tonum(mpData.get("pay_money"));
		double plan_money = StringUtil.tonum(mpData.get("plan_money"));
		double contract_money = StringUtil.tonum(mpData.get("contract_money"));
		
		return pay_money + plan_money > contract_money;
	}
	
	/**
	 * 月份计划提交前检查：同一个单位同一个月不能有两条月度计划；如果没有明细计划不能提交；付款月度不能小于当前月度；
	 * @param mpayIds
	 * @return
	 */
	public String preAudit(String[] mpayIds) {
		if (mpayIds == null || mpayIds.length == 0) {
			setMessage("没有选择月度付款计划！");
			return _returnFaild;
		}
		
		for (int i = 0, n = mpayIds.length; i < n; i++) {
			if (!checkMplan(mpayIds[i])) {
				return _returnFaild;
			}
		}
		
		return _returnSuccess;
	}
	
	/**
	 * 汇总该单位的月度付款计划
	 * @param mpayid
	 * @return
	 */
	public String statPlan(String mpayid) {
		Map<String,String> mpData = queryMpay(mpayid);
		
		String deptId = mpData.get("dept_id");
		String payMonth = mpData.get("pay_month");
		String isinfo = mpData.get("is_info");
		_log.showDebug("-----deptId=" + deptId + ";payMonth=" + payMonth+" ;is_info"+isinfo);
		updateSubPlan(mpayid, deptId, payMonth ,isinfo);
		
		updateMoney(mpayid);
		
		return _returnSuccess;
	}
	
	//取消付款计划
	public String cancelPay(String[] payIds) {
		if (payIds == null || payIds.length == 0) {
			setMessage("没有选择要取消的付款计划！");
			return _returnFaild;
		}
		
		for (int i = 0, n = payIds.length; i < n; i++) {
			if (!cancelPay(payIds[i])) {
				return _returnFaild;
			}
		}
		
		return _returnSuccess;
	}
	
	//取消付款计划
	private boolean cancelPay(String payId) {
		String sql = "update contract_pay set check_money = 0, plan_status = '3' where pay_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(payId);
		
		return _dao.update(param);
	}
	
	//检查
	private boolean checkMplan(String mpayid) {
		Map<String,String> mpData = queryMpay(mpayid);
		
		String dept_id = mpData.get("dept_id");
		String pay_month = mpData.get("pay_month");
		String isinfo = mpData.get("is_info");
		_log.showDebug("--------dept_id" + dept_id + ";pay_month=" + pay_month+" ;is_info"+isinfo);
		/*String cur_month = DateUtil.getCurrYearMonth();
		if (pay_month.compareTo(cur_month) < 0) {
			setMessage("计划月度不能小于当前月度！");
			return false;
		}*/
		
		if (hasMoreMpay(dept_id, pay_month,isinfo) > 1) {
			setMessage("同一个单位同一个月不能有两条月度计划！");
			return false;
		}
		
		if (!hasSubPlan(mpayid)) {
			setMessage("没有付款计划明细，不能提交！");
			return false;
		}
		
		//累计付款金额不能大于合同金额
		
		
		return true;
	}
	
	//更新付款计划中的月度ID
	private boolean updateSubPlan(String mpayid, String deptId, String payMonth ,String isinfo) {
		//取开始与结束日期
		String[] months = DateUtil.getDateByMonth(payMonth);
		
		String sql = "update contract_pay set check_money = plan_money, mpay_id = ? " +
				"where dept_id like ? and plan_month >= ? and plan_month < ? and plan_status = '1' and auditing='1'";
		if (isinfo.equals("0")) {
			sql += "and money_type <> '60' ";
		} else {
			sql += "and money_type = '60' ";
		}
		//特殊处理：许昌烟厂要把许昌技改项目部的剔除
		if (deptId.equals("1004")) {
			sql += "and dept_id not like '10040029%' ";
		} 
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(mpayid);
		param.addStringValue(deptId+"%");
		param.addDateValue(months[0]);
		param.addDateValue(months[1]);
		
		
		return _dao.update(param);
	}
	
	//合计付款计划金额到主表中
	private boolean updateMoney(String mpayid) {
		String sql1 = "select sum(plan_money) as plan_money, sum(check_money) as check_money, count(*) as num1 " +
				"from contract_pay where mpay_id = ?";
		DaoParam param1 = _dao.createParam(sql1);
		param1.addStringValue(mpayid);
		Map<String,String> mp = _dao.queryMap(param1);
		String plan_money = MapUtil.getValue(mp, "plan_money", "0");
		String check_money = MapUtil.getValue(mp, "check_money", "0");
		String pay_num = MapUtil.getValue(mp, "num1", "0");
		
		String usql = "update contract_mpay set plan_money = ?, check_money = ?,pay_num=? where mpay_id = ?";
		DaoParam uparam = _dao.createParam(usql);
		uparam.addDoubleValue(plan_money);
		uparam.addDoubleValue(check_money);
		uparam.addDoubleValue(pay_num);
		uparam.addStringValue(mpayid);
		
		return _dao.update(uparam);
	}
	
	//检查是否有子计划
	private boolean hasSubPlan(String mpayid) {
		String sql = "select count(*) as cnt from contract_pay where mpay_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(mpayid);
		
		return MapUtil.hasRecord(_dao.queryMap(param));
	}
	
	//检查是否有多条同月度的计划
	private int hasMoreMpay(String deptId, String payMonth ,String isinfo) {
		//取开始与结束日期
		String[] months = DateUtil.getDateByMonth(payMonth);
		
		String sql = "select count(*) as cnt from contract_mpay where dept_id = ? and pay_month >= ? and pay_month < ? and is_info = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(deptId);
		param.addDateValue(months[0]);
		param.addDateValue(months[1]);
		param.addStringValue(isinfo);
		
		return MapUtil.hasRecodNum(_dao.queryMap(param));
	}
	
	//取月度计划
	private Map<String,String> queryMpay(String mpayid) {
		String sql = "select dept_id, to_char(pay_month, 'yyyy-mm') as pay_month ,is_info from contract_mpay where mpay_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(mpayid);
		
		return _dao.queryMap(param);
	}
}
